package edu.ksu.cis.indus.tools.slicer;

import edu.ksu.cis.indus.common.collections.CollectionsUtilities;
import edu.ksu.cis.indus.common.datastructures.Pair;
import edu.ksu.cis.indus.common.datastructures.Pair.PairManager;
import edu.ksu.cis.indus.common.scoping.SpecificationBasedScopeDefinition;
import edu.ksu.cis.indus.common.soot.BasicBlockGraphMgr;
import edu.ksu.cis.indus.common.soot.IStmtGraphFactory;
import edu.ksu.cis.indus.interfaces.IActivePart;
import edu.ksu.cis.indus.interfaces.IActivePart.ActivePart;
import edu.ksu.cis.indus.interfaces.ICallGraphInfo;
import edu.ksu.cis.indus.interfaces.IEnvironment;
import edu.ksu.cis.indus.interfaces.IEscapeInfo;
import edu.ksu.cis.indus.interfaces.IMonitorInfo;
import edu.ksu.cis.indus.interfaces.IThreadGraphInfo;
import edu.ksu.cis.indus.processing.OneAllStmtSequenceRetriever;
import edu.ksu.cis.indus.processing.TagBasedProcessingFilter;
import edu.ksu.cis.indus.slicer.ISliceCriterion;
import edu.ksu.cis.indus.slicer.SliceCollector;
import edu.ksu.cis.indus.slicer.SliceCriteriaFactory;
import edu.ksu.cis.indus.slicer.SlicingEngine;
import edu.ksu.cis.indus.staticanalyses.callgraphs.CallGraphInfo;
import edu.ksu.cis.indus.staticanalyses.callgraphs.OFABasedCallInfoCollector;
import edu.ksu.cis.indus.staticanalyses.cfg.CFGAnalysis;
import edu.ksu.cis.indus.staticanalyses.cfg.ExceptionRaisingAnalysis;
import edu.ksu.cis.indus.staticanalyses.cfg.StaticFieldUseDefInfo;
import edu.ksu.cis.indus.staticanalyses.concurrency.MonitorAnalysis;
import edu.ksu.cis.indus.staticanalyses.concurrency.SafeLockAnalysis;
import edu.ksu.cis.indus.staticanalyses.concurrency.escape.DataAliasBasedCallingContextRetrieverV2;
import edu.ksu.cis.indus.staticanalyses.concurrency.escape.EquivalenceClassBasedEscapeAnalysis;
import edu.ksu.cis.indus.staticanalyses.concurrency.escape.ThreadEscapeInfoBasedCallingContextRetriever;
import edu.ksu.cis.indus.staticanalyses.concurrency.escape.ThreadEscapeInfoBasedCallingContextRetrieverV2;
import edu.ksu.cis.indus.staticanalyses.dependency.IDependencyAnalysis;
import edu.ksu.cis.indus.staticanalyses.flow.instances.ofa.OFAnalyzer;
import edu.ksu.cis.indus.staticanalyses.flow.instances.ofa.processors.AliasedUseDefInfov2;
import edu.ksu.cis.indus.staticanalyses.flow.instances.ofa.processors.NewExpr2InitMapper;
import edu.ksu.cis.indus.staticanalyses.flow.instances.ofa.processors.ThreadGraph;
import edu.ksu.cis.indus.staticanalyses.interfaces.IValueAnalyzer;
import edu.ksu.cis.indus.staticanalyses.processing.AnalysesController;
import edu.ksu.cis.indus.staticanalyses.processing.CGBasedProcessingFilter;
import edu.ksu.cis.indus.staticanalyses.processing.ValueAnalyzerBasedProcessingController;
import edu.ksu.cis.indus.staticanalyses.tokens.ITokenManager;
import edu.ksu.cis.indus.tools.AbstractTool;
import edu.ksu.cis.indus.tools.CompositeToolConfiguration;
import edu.ksu.cis.indus.tools.CompositeToolConfigurator;
import edu.ksu.cis.indus.tools.IToolConfiguration;
import edu.ksu.cis.indus.tools.IToolConfigurationFactory;
import edu.ksu.cis.indus.tools.Phase;
import edu.ksu.cis.indus.tools.slicer.criteria.generators.ISliceCriteriaGenerator;
import edu.ksu.cis.indus.tools.slicer.processing.ExecutableSlicePostProcessor;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import soot.SootMethod;

public final class SlicerTool extends AbstractTool
{
  public static final Object DEPENDENCE_MAJOR_PHASE;
  public static final String FLOW_ANALYSIS_TAG_NAME = "indus.tools.slicer.SlicerTool:FA";
  public static final Object SLICE_MAJOR_PHASE;
  private static final int INDENT = 4;
  private static final Logger LOGGER = LoggerFactory.getLogger(SlicerTool.class);

  private final IActivePart.ActivePart activePart = new IActivePart.ActivePart();
  private AliasedUseDefInfov2 aliasUD;
  private final BasicBlockGraphMgr bbgMgr;
  private final CallGraphInfo callGraph;
  private final ValueAnalyzerBasedProcessingController cgBasedPreProcessCtrl;
  private final ValueAnalyzerBasedProcessingController cgPreProcessCtrl;
  private final Collection<ISliceCriterion> criteria;
  private final Collection<ISliceCriteriaGenerator> criteriaGenerators;
  private AnalysesController daController;
  private EquivalenceClassBasedEscapeAnalysis ecba;
  private final SlicingEngine engine;
  private final Map info;
  private NewExpr2InitMapper initMapper;
  private final MonitorAnalysis monitorInfo;
  private final OFAnalyzer ofa;
  private final Pair.PairManager pairMgr;
  private Phase phase;
  private final Collection<SootMethod> rootMethods;
  private final SafeLockAnalysis safelockAnalysis;
  private SpecificationBasedScopeDefinition sliceScopeDefinition;
  private final StaticFieldUseDefInfo staticFieldUD;
  private final IStmtGraphFactory stmtGraphFactory;
  private IEnvironment system;
  private final ITokenManager theTokenMgr;
  private final ThreadGraph threadGraph;

  static
  {
    Phase _i = Phase.createPhase();
    _i.nextMajorPhase();
    DEPENDENCE_MAJOR_PHASE = _i.clone();
    _i.nextMajorPhase();
    SLICE_MAJOR_PHASE = _i.clone();
  }

  public SlicerTool(ITokenManager tokenMgr, IStmtGraphFactory stmtGraphFactoryToUse)
  {
    this.theTokenMgr = tokenMgr;
    this.phase = Phase.createPhase();

    this.rootMethods = new HashSet();
    this.criteria = new HashSet();
    this.info = new HashMap();
    this.criteriaGenerators = new HashSet();

    this.stmtGraphFactory = stmtGraphFactoryToUse;

    this.ofa = OFAnalyzer.getFSOSAnalyzer("indus.tools.slicer.SlicerTool:FA", tokenMgr, getStmtGraphFactory());
    addActivePart(this.ofa.getActivePart());

    this.cgPreProcessCtrl = new ValueAnalyzerBasedProcessingController();
    this.cgPreProcessCtrl.setAnalyzer(this.ofa);
    this.cgPreProcessCtrl.setProcessingFilter(new TagBasedProcessingFilter("indus.tools.slicer.SlicerTool:FA"));

    OneAllStmtSequenceRetriever _ssr = new OneAllStmtSequenceRetriever();
    this.cgPreProcessCtrl.setStmtSequencesRetriever(_ssr);

    addActivePart(this.cgPreProcessCtrl.getActivePart());

    this.pairMgr = new Pair.PairManager(false, true);

    this.callGraph = new CallGraphInfo(this.pairMgr);

    this.cgBasedPreProcessCtrl = new ValueAnalyzerBasedProcessingController();
    this.cgBasedPreProcessCtrl.setProcessingFilter(new CGBasedProcessingFilter(this.callGraph));
    this.cgBasedPreProcessCtrl.setAnalyzer(this.ofa);
    this.cgBasedPreProcessCtrl.setStmtSequencesRetriever(_ssr);

    addActivePart(this.cgBasedPreProcessCtrl.getActivePart());

    this.bbgMgr = new BasicBlockGraphMgr();
    this.bbgMgr.setStmtGraphFactory(getStmtGraphFactory());
    _ssr.setBbgFactory(this.bbgMgr);

    this.threadGraph = new ThreadGraph(this.callGraph, new CFGAnalysis(this.callGraph, this.bbgMgr), this.pairMgr);

    this.ecba = new EquivalenceClassBasedEscapeAnalysis(this.callGraph, null, this.bbgMgr);

    this.monitorInfo = new MonitorAnalysis();

    this.safelockAnalysis = new SafeLockAnalysis();

    this.aliasUD = new AliasedUseDefInfov2(this.ofa, this.callGraph, this.threadGraph, this.bbgMgr, this.pairMgr);

    this.staticFieldUD = new StaticFieldUseDefInfo();

    this.info.put(ICallGraphInfo.ID, this.callGraph);
    this.info.put(IThreadGraphInfo.ID, this.threadGraph);
    this.info.put(IEnvironment.ID, this.ofa.getEnvironment());
    this.info.put("Aliased Use-Def Information", this.aliasUD);
    this.info.put("Global Use-Def Information", this.staticFieldUD);
    this.info.put(Pair.PairManager.ID, this.pairMgr);
    this.info.put(IValueAnalyzer.ID, this.ofa);
    this.info.put(IEscapeInfo.ID, this.ecba.getEscapeInfo());
    this.info.put(IMonitorInfo.ID, this.monitorInfo);
    this.info.put(SafeLockAnalysis.ID, this.safelockAnalysis);

    this.engine = new SlicingEngine();
    addActivePart(this.engine.getActivePart());

    this.initMapper = new NewExpr2InitMapper();

    addActivePart(this.activePart);
  }

  public void addCriteria(Collection<ISliceCriterion> theCriteria)
  {
    this.criteria.addAll(theCriteria);
  }

/*  public boolean addCriteriaGenerator(ISliceCriteriaGenerator theCriteriaGenerator)
  {
    return this.criteriaGenerators.add(theCriteriaGenerator);
  }*/

  public void clearCriteria()
  {
    this.criteria.clear();
  }

  public boolean destringizeConfiguration(String stringizedForm)
  {
    boolean _result = false;
    IUnmarshallingContext _unmarshallingContext;
    try {
      IBindingFactory _bindingFactory = BindingDirectory.getFactory(CompositeToolConfiguration.class);
      _unmarshallingContext = _bindingFactory.createUnmarshallingContext();
    } catch (JiBXException _e) {
      LOGGER.error("Error while setting up JiBX.  Aborting.", _e);
      throw new RuntimeException(_e);
    }
//    IUnmarshallingContext _unmarshallingContext;
//    IBindingFactory _bindingFactory;
    this.configurationInfo = null;

    if ((stringizedForm != null) && (stringizedForm.length() != 0)) {
      try {
        StringReader _reader = new StringReader(stringizedForm);
        this.configurationInfo = ((IToolConfiguration)_unmarshallingContext.unmarshalDocument(_reader, null));
        _result = true;
      } catch (JiBXException _e) {
        LOGGER.error("Error while unmarshalling Slicer configurationCollection. Recovering with new clean configuration.", 
          _e);
        this.configurationInfo = null;
      }
    }

    if (this.configurationInfo == null) {
      initialize();
    }

    this.configurator = 
      new CompositeToolConfigurator((CompositeToolConfiguration)this.configurationInfo, 
      new SlicerConfigurator(), SlicerConfiguration.getFactory());
    return _result;
  }

  public void execute(Phase phaseParam, Phase lastPhase)
    throws InterruptedException
  {
	 
    if (LOGGER.isInfoEnabled()) {
      LOGGER.info("BEGIN: Execution of the slicer tool");
    }

    Phase _ph = this.phase;

    if ((phaseParam != null) && (phaseParam.isEarlierThan(this.phase))) {
      this.phase = ((Phase)phaseParam.clone());
      _ph = this.phase;
    }

    if (_ph.equalsMajor(Phase.STARTING_PHASE)) {
      fireToolProgressEvent("Performing low level analyses", _ph);
      lowLevelAnalysisPhase();
    }

    if (this.phase.equals(lastPhase)) {
      return;
    }

    movingToNextPhase();

    SlicerConfiguration _slicerConfig = (SlicerConfiguration)getActiveConfiguration();
   
    setCurrentConfiguration(_slicerConfig);
    _slicerConfig.setupForUse();

    if (_ph.equalsMajor((Phase)DEPENDENCE_MAJOR_PHASE)) {
      fireToolProgressEvent("Performing dependence analyses", _ph);
      dependencyAnalysisPhase(_slicerConfig);
    }

    if (this.phase.equals(lastPhase)) {
      return;
    }

    movingToNextPhase();

    if (_ph.equalsMajor((Phase)SLICE_MAJOR_PHASE)) {
      fireToolProgressEvent("Performing slicing", _ph);
      slicingPhase(_slicerConfig);
    }
    this.phase.finished();

    if (LOGGER.isInfoEnabled())
      LOGGER.info("END: Execution of the slicer tool");
  }

  public BasicBlockGraphMgr getBasicBlockGraphManager()
  {
    return this.bbgMgr;
  }

  public ICallGraphInfo getCallGraph()
  {
    return this.callGraph;
  }

  public Collection getCriteria()
  {
    return this.criteria;
  }

  public Collection<IDependencyAnalysis> getDAs()
  {
    Collection _result = new LinkedHashSet();
    SlicerConfiguration _config = (SlicerConfiguration)getActiveConfiguration();
    List _daNames = new ArrayList(_config.getIDsOfDAsToUse());
    Collections.sort(_daNames);

    for (Iterator _i = _daNames.iterator(); _i.hasNext(); ) {
      _result.addAll(_config.getDependenceAnalyses(_i.next()));
    }
    return _result;
  }

  public EquivalenceClassBasedEscapeAnalysis getECBA()
  {
    return this.ecba;
  }

  public IEscapeInfo getEscapeInfo()
  {
    return this.ecba.getEscapeInfo();
  }

  public MonitorAnalysis getMonitorInfo()
  {
    return this.monitorInfo;
  }

  public Object getPhase()
  {
    return this.phase;
  }

  public Collection getRootMethods()
  {
    return Collections.unmodifiableCollection(this.rootMethods);
  }

  public IStmtGraphFactory getStmtGraphFactory()
  {
    return this.stmtGraphFactory;
  }

  public IEnvironment getSystem()
  {
    return this.system;
  }

  public void initialize()
  {
    this.configurationInfo = new CompositeToolConfiguration();

    IToolConfiguration _toolConfig = SlicerConfiguration.getFactory().createToolConfiguration();
    _toolConfig.initialize();
    ((CompositeToolConfiguration)this.configurationInfo).addToolConfiguration(_toolConfig);
  }

  public boolean removeCriteriaGenerator(ISliceCriteriaGenerator theCriteriaGenerator)
  {
    return this.criteriaGenerators.remove(theCriteriaGenerator);
  }

  public void reset()
  {
    this.aliasUD.reset();
    this.bbgMgr.reset();
    this.callGraph.reset();
    this.cgBasedPreProcessCtrl.reset();
    this.cgPreProcessCtrl.reset();
    this.criteria.clear();
    this.ecba.reset();
    this.engine.reset();
    this.initMapper.reset();
    this.monitorInfo.reset();
    this.ofa.reset();
    this.pairMgr.reset();
    this.phase.reset();
    this.rootMethods.clear();
    this.safelockAnalysis.reset();
    this.stmtGraphFactory.reset();
    this.theTokenMgr.reset();
    this.threadGraph.reset();
    this.activePart.activate();
  }

  public void setActiveConfiguration(String configID)
  {
    if (this.configurationInfo instanceof CompositeToolConfiguration)
      ((CompositeToolConfiguration)this.configurationInfo).setActiveToolConfigurationID(configID);
  }

  public void setRootMethods(Collection<SootMethod> theRootMethods)
  {
    this.rootMethods.clear();
    this.rootMethods.addAll(theRootMethods);
  }

  public void setSliceScopeDefinition(SpecificationBasedScopeDefinition scope)
  {
    this.sliceScopeDefinition = scope;
  }

  public void setSystem(IEnvironment theEnvironment)
  {
    this.system = theEnvironment;
  }

  public void setTagName(String tagName)
  {
    this.engine.setTagName(tagName);
  }

  public String stringizeConfiguration()
  {
    StringWriter _result = new StringWriter();
    try
    {
      IBindingFactory _bindingFactory = BindingDirectory.getFactory(CompositeToolConfiguration.class);
      IMarshallingContext _marshallingContext = _bindingFactory.createMarshallingContext();
      _marshallingContext.setIndent(4);
      _marshallingContext.marshalDocument(this.configurationInfo, "UTF-8", null, _result);
    } catch (JiBXException _e) {
      LOGGER.error("Error while marshalling Slicer configurationCollection.");
      throw new RuntimeException(_e);
    }
    return _result.toString();
  }

  protected void checkConfiguration()
  {
    IToolConfiguration _slicerConf = getActiveConfiguration();

    if ((((Boolean)_slicerConf.getProperty(SlicerConfiguration.EXECUTABLE_SLICE)).booleanValue()) && 
      (_slicerConf.getProperty(SlicerConfiguration.SLICE_TYPE).equals(SlicingEngine.FORWARD_SLICE))) {
      LOGGER.error("Forward Executable slice is unsupported.");
      throw new IllegalStateException("Forward Executable slice is unsupported.");
    }

    if (LOGGER.isDebugEnabled())
      LOGGER.debug("checkConfiguration() - " + _slicerConf.getConfigName());
  }

  SliceCollector getSliceCollector()
  {
    return this.engine.getCollector();
  }

  private void dependencyAnalysisPhase(SlicerConfiguration slicerConfig)
  {
    if (LOGGER.isInfoEnabled())
      LOGGER.info("BEGIN: dependence analyses phase");
    BasicBlockGraphMgr _b;
    if (slicerConfig.isExplicitExceptionalExitSensitiveControlDependenceUsed()) {
      ExceptionRaisingAnalysis _e = new ExceptionRaisingAnalysis(getStmtGraphFactory(), getCallGraph(), 
        getSystem());

      if (slicerConfig.areCommonUncheckedExceptionsConsidered()) {
        _e.setupForCommonUncheckedExceptions();
      }
      _e.hookup(this.cgBasedPreProcessCtrl);
      this.cgBasedPreProcessCtrl.process();
      _e.unhook(this.cgBasedPreProcessCtrl);

      /*BasicBlockGraphMgr*/ _b = new BasicBlockGraphMgr(_e);
      _b.setStmtGraphFactory(getStmtGraphFactory());
    } else {
      _b = getBasicBlockGraphManager();
    }
    this.daController = new AnalysesController(this.info, this.cgBasedPreProcessCtrl, _b);
    addActivePart(this.daController.getActivePart());

    Collection _controlDAs = slicerConfig
      .getDependenceAnalyses(IDependencyAnalysis.CONTROL_DA);
    CollectionsUtilities.getSetFromMap(this.info, IDependencyAnalysis.CONTROL_DA).addAll(_controlDAs);

    for (Iterator _i = slicerConfig.getIDsOfDAsToUse().iterator(); _i.hasNext(); ) {
      Object _id = _i.next();
      Collection _c = slicerConfig.getDependenceAnalyses(_id);
      this.daController.addAnalyses(_id, _c);
    }
    this.daController.addAnalyses(IMonitorInfo.ID, (Collection)Collections.singleton(this.monitorInfo));
    this.daController.addAnalyses(EquivalenceClassBasedEscapeAnalysis.ID, (Collection)Collections.singleton(this.ecba));

    if (slicerConfig.isSafeLockAnalysisUsedForReady()) {
      this.daController.addAnalyses(SafeLockAnalysis.ID, (Collection)Collections.singleton(this.safelockAnalysis));
    }
    this.daController.initialize();
    this.daController.execute();
    removeActivePart(this.daController.getActivePart());

    String _deadlockCriteriaSelectionStrategy = slicerConfig.getDeadlockCriteriaSelectionStrategy();

    if ((!(slicerConfig.getPropertyAware())) && 
      (!(_deadlockCriteriaSelectionStrategy.equals(SlicerConfiguration.CONTEXT_SENSITIVE_ESCAPING_SYNC_CONSTRUCTS)))) {
      this.ecba.flushSiteContexts();
    }

    this.phase.nextMajorPhase();

    if (LOGGER.isInfoEnabled())
      LOGGER.info("END: dependence analyses phase");
  }

  private void lowLevelAnalysisPhase()
    throws InterruptedException
  {
    if (LOGGER.isInfoEnabled()) {
      LOGGER.info("BEGIN: low level static analyses phase");
    }

    fireToolProgressEvent("LOW LEVEL ANALYSES: Performing object flow analysis", this.phase);

    this.phase.reset();

    this.ofa.reset();
    this.bbgMgr.reset();
    this.stmtGraphFactory.reset();
    this.ofa.analyze(this.system, this.rootMethods);
    this.phase.nextMinorPhase();

    movingToNextPhase();

    fireToolProgressEvent("LOW LEVEL ANALYSES: Constructing call graph", this.phase);

    OFABasedCallInfoCollector _callGraphInfoCollector = new OFABasedCallInfoCollector();
    this.cgPreProcessCtrl.reset();
    _callGraphInfoCollector.hookup(this.cgPreProcessCtrl);
    this.cgPreProcessCtrl.process();
    _callGraphInfoCollector.unhook(this.cgPreProcessCtrl);

    this.callGraph.reset();
    this.callGraph.createCallGraphInfo(_callGraphInfoCollector.getCallInfo());
    this.phase.nextMinorPhase();

    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug("Call Graph:\n" + this.callGraph);
    }

    movingToNextPhase();

    fireToolProgressEvent("LOW LEVEL ANALYSES: Constructing thread graph and misc.", this.phase);

    this.threadGraph.reset();
    this.cgBasedPreProcessCtrl.reset();
    this.initMapper.hookup(this.cgBasedPreProcessCtrl);
    this.threadGraph.hookup(this.cgBasedPreProcessCtrl);
    this.cgBasedPreProcessCtrl.process();
    this.threadGraph.unhook(this.cgBasedPreProcessCtrl);
    this.initMapper.unhook(this.cgBasedPreProcessCtrl);
    this.phase.nextMinorPhase();

    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug("Thread Graph:\n" + this.threadGraph);
    }

    movingToNextPhase();

    fireToolProgressEvent("LOW LEVEL ANALYSES: Calculating intra-procedural use-def information", this.phase);

    this.cgBasedPreProcessCtrl.reset();
    this.aliasUD.reset();
    this.aliasUD.hookup(this.cgBasedPreProcessCtrl);
    this.staticFieldUD.reset();
    this.staticFieldUD.hookup(this.cgBasedPreProcessCtrl);
    this.cgBasedPreProcessCtrl.process();
    this.aliasUD.unhook(this.cgBasedPreProcessCtrl);
    this.staticFieldUD.unhook(this.cgBasedPreProcessCtrl);

    this.phase.nextMajorPhase();

    if (LOGGER.isInfoEnabled())
      LOGGER.info("END: low level static analyses phase");
  }

  private void postProcessSlice()
  {
    SlicerConfiguration _slicerConfig = (SlicerConfiguration)getActiveConfiguration();

    if (_slicerConfig.getExecutableSlice())
      SlicerToolHelper.applyPostProcessor(this, new ExecutableSlicePostProcessor());
  }

  private void slicingPhase(SlicerConfiguration slicerConfig)
  {
    if (LOGGER.isInfoEnabled()) {
      LOGGER.info("BEGIN: slicing phase");
    }
    
    //TODO wxq
    slicerConfig.setExecutableSlice(true);

    this.engine.reset();

    fireToolProgressEvent("SLICING: adding criteria", this.phase);

    for (Iterator _i = this.criteriaGenerators.iterator(); _i.hasNext(); ) {
      ISliceCriteriaGenerator _e = (ISliceCriteriaGenerator)_i.next();
      this.criteria.addAll(_e.getCriteria(this));
    }

    for (Iterator _j = slicerConfig.getSliceCriteriaGenerators().iterator(); _j.hasNext(); ) {
      ISliceCriteriaGenerator _generator = (ISliceCriteriaGenerator)_j.next();
      this.criteria.addAll(_generator.getCriteria(this));
    }

    if (!(this.criteria.isEmpty())) {
      fireToolProgressEvent("SLICING: Calculating the slice", this.phase);

      this.engine.setCgi(this.callGraph);
      this.engine.setSliceType(slicerConfig.getProperty(SlicerConfiguration.SLICE_TYPE));
      this.engine.setInitMapper(this.initMapper);
      this.engine.setBasicBlockGraphManager(this.bbgMgr);
      this.engine.setAnalysesControllerAndDependenciesToUse(this.daController, slicerConfig.getIDsOfDAsToUse());
      this.engine.setSliceCriteria(this.criteria);
      this.engine.setSliceScopeDefinition(this.sliceScopeDefinition);
      this.engine.setSystem(this.system);


      if (slicerConfig.getPropertyAware()) {
        Map _map = new HashMap();
        int _callingContextLimit = slicerConfig.getCallingContextLimit();
        ThreadEscapeInfoBasedCallingContextRetriever _t1 = new ThreadEscapeInfoBasedCallingContextRetrieverV2(
          _callingContextLimit, IDependencyAnalysis.READY_DA);

        _t1.setEscapeInfo(getEscapeInfo());
        _t1.setECBA(this.ecba);
        _t1.setCallGraph(getCallGraph());
        _map.put(IDependencyAnalysis.READY_DA, _t1);

        ThreadEscapeInfoBasedCallingContextRetriever _t2 = new ThreadEscapeInfoBasedCallingContextRetrieverV2(
          _callingContextLimit, IDependencyAnalysis.INTERFERENCE_DA);

        _t2.setEscapeInfo(getEscapeInfo());
        _t2.setECBA(this.ecba);
        _t2.setCallGraph(getCallGraph());
        _map.put(IDependencyAnalysis.INTERFERENCE_DA, _t2);

        DataAliasBasedCallingContextRetrieverV2 _t3 = new DataAliasBasedCallingContextRetrieverV2(
          _callingContextLimit);
        _t3.setCallGraph(getCallGraph());
        _t3.setThreadGraph(this.threadGraph);
        _t3.setCfgAnalysis(new CFGAnalysis(getCallGraph(), getBasicBlockGraphManager()));
        _t3.setECBA(this.ecba);
        _map.put(IDependencyAnalysis.REFERENCE_BASED_DATA_DA, _t3);
        this.engine.setDepID2ContextRetrieverMapping(_map);
      }
      this.engine.initialize();
      this.engine.slice();
      this.phase.nextMinorPhase();

      fireToolProgressEvent("SLICING: Post processing the slice", this.phase);

      postProcessSlice();

      this.phase.nextMajorPhase();
    }
    else if (LOGGER.isWarnEnabled()) {
      LOGGER.warn("No slicing criteria were specified. Hence, no slicing was done.\nIf \"slice for deadlock\" was selected then the system did not have any synchronized methods or synchronized blocks.");
    }

    if (LOGGER.isInfoEnabled())
      LOGGER.info("END: slicing phase");
  }
}

/* Location:           D:\tool\banderaCLI-1.0a4\lib\indus\slicer.jar
 * Qualified Name:     edu.ksu.cis.indus.tools.slicer.SlicerTool
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.5.3
 */